# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import rethinkdb as r
from .items import Chapter, Novel, Book
from .models import db
from peewee import PostgresqlDatabase
from .tasks import save_chapter, save_novel, save_ebook
from .tasks import save_torrent
from .appcan import save_apk, AppItem

class TorrentPipeline(object):
    def process_item(self, item, spider):
        if isinstance(item, Torrent):
            save_torrent(item)
        return item

class RobotPipeline(object):
    def process_item(self, item, spider):
        return item


class HetuPipeline(object):
    def _parse_book_id(self, url):
        s = url.find('/book/')
        e = url.find('/', s + 6)
        return int(url[s + 6:e])

    def _parse_chapter_id(self, url):
        s = url.rfind('/')
        return int(url[s + 1:].replace('.html', ''))

    def process_item(self, item, spider):
        if isinstance(item, Novel):
            source_url = item.get('source_url', None)
            if source_url:
                book_id = self._parse_book_id(source_url)
                item['id'] = book_id
        elif isinstance(item, Chapter):
            source_url = item.get('source_url', None)
            if source_url:
                item['book_id'] = self._parse_book_id(source_url)
                item['id'] = self._parse_chapter_id(source_url)
        return item


class RethinkdbPipeline(object):
    def __init__(self, db):
        self.db = db

    @classmethod
    def from_crawler(cls, crawler):
        conf = crawler.settings.get('RETHINKDB')
        conn = r.connect(**conf)
        return cls(db=conn)

    def open_spider(self, spider):
        pass

    def close_spider(self, spider):
        self.db.close()

    def process_item(self, item, spider):
        if isinstance(item, Novel):
            novel = r.table('novel').get(item.get('id')).run(self.db)
            if novel:
                r.table('novel').get(item.get('id')).update(
                    dict(item)).run(self.db)
            else:
                r.table('novel').insert(dict(item)).run(self.db)
        elif isinstance(item, Chapter):
            chapter = r.table('chapter').filter({'book_id': item.get(
                'book_id'), 'sort_no': item.get('sort_no')}).count().run(self.db)
            if chapter:
                r.table('chapter').filter({'book_id': item.get(
                    'book_id'), 'sort_no': item.get('sort_no')}).update(dict(item)).run(self.db)
            else:
                r.table('chapter').insert(dict(item)).run(self.db)
        return item


class PeeweePipeline(object):
    def __init__(self, db):
        self.db = db

    @classmethod
    def from_crawler(cls, crawler):
        conf = crawler.settings.get('PEEWEE_DB_URI')
        database = PostgresqlDatabase(conf['db'], **conf)
        db.initialize(database)
        return cls(db=database)

    def open_spider(self, spider):
        pass

    def close_spider(self, spider):
        self.db.close()

    def process_item(self, item, spider):
        if isinstance(item, Novel):
            novel = NovelModel.get_or_none(NovelModel.id == item.get('id'))
            if novel:
                novel.__data__.update(dict(item))
                novel.save()
            else:
                NovelModel.create(**dict(item))

        elif isinstance(item, Chapter):
            chapter = ChapterModel.get_or_none(ChapterModel.book_id == item.get(
                'book_id'), ChapterModel.sort_no == item.get('sort_no'))
            if chapter:
                chapter.__data__.update(dict(item))
                chapter.save()
            else:
                ChapterModel.create(**dict(item))
        return item


class CeleryPipeline(object):
    def process_item(self, item, spider):
        if isinstance(item, Novel):
            save_novel.delay(dict(item))
        elif isinstance(item, Chapter):
            save_chapter.delay(dict(item))
        elif isinstance(item, Book):
            save_ebook.delay(dict((item)))
        elif isinstance(item, AppItem):
            save_apk.delay(dict((item)))
        return item
